class User < ActiveRecord::Base

  has_many :jobs, :dependent => :destroy

  @@ALPHABET = ['0'..'9', 'a'..'z', 'A'..'Z'].map { |c| c.to_a }.flatten!

  validates_presence_of :password_hash, :salt, :if => :email
  validates_presence_of :email, :if => [:password_hash, :salt]
  validates_uniqueness_of :email, :allow_nil => true
  validates_format_of :email, :with => RFC822::EmailAddress, :allow_nil => :true
  validates_length_of :password, :minimum => 8, :allow_nil => true
  validates_confirmation_of :password, :if => lambda { |user| user.password  }

  attr_accessible :email, :password, :password_confirmation, :send_email
  attr_accessor :password, :password_confirmation

  def reset_password_and_send_account_info!
    self.password = User.generate_random_string(8)
    Mailer.send_later(:deliver, Mailer.create_signup_notification(self))
    save
  end

  def temporary_user?
    email.nil? && password_hash.nil?
  end

  def password=(password)
    if password && !password.empty?
      @password = password
      self.salt ||= User.generate_random_string(16)
      self.password_hash = User.hash_password(password, self.salt)
    end
  end

  def correct_password?(password)
    password && self.password_hash == User.hash_password(password, self.salt)
  end

  def self.authenticate(email, password)
    user = User.find(:first, :conditions => { :email => email })
    if user && user.correct_password?(password)
      user
    else
      raise AuthenticationError
    end
  end

  def self.hash_password(password, salt)
    Digest::SHA2::hexdigest(password + salt)
  end

  def self.generate_random_string(length = 16)
    (1..length).map { @@ALPHABET.choice }.join
  end
end

class AuthenticationError < Exception
end
